﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "ICurve2d.h"

namespace gcmp
{
    /// \brief 二维圆弧
    ///
    class IArc2d : public ICurve2d
    {
        DEFINE_CAST_DERIVED(gcmp::IArc2d, gcmp::ICurve2d);
    public:

        /// \brief 根据圆心，半径，起始弧度，终止弧度（默认逆时针）
        /// \param centerPoint   坐标系原点，圆弧圆心
        /// \param radius     圆弧半径
        /// \param startAngle 起始弧度
        /// \param endAngle   终止弧度
        /// \param antiClockwise  弧顺逆方向，true：逆时， false：顺时
        /// \return 二维圆弧
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc2d> Create(const Vector2d &centerPoint, double radius, double startAngle, double endAngle, bool antiClockwise = true);

        /// \brief 根据空间中三点构造空间平面圆弧曲线
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param referencePoint    参考点
        /// \return 二维圆弧
        /// \see 要求三点不重合且不共线
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc2d> Create(const Vector2d &startPoint, const Vector2d &endPoint, const Vector2d &referencePoint);

        /// \brief 根据圆心、半径，起始点和终止点，以及顺逆方向来构造圆弧
        /// \param centerPoint 圆心
        /// \param startPoint 起点坐标，起点与圆心的距离决定半径的大小
        /// \param endPoint 终点坐标，终点与圆心的矢量决定终止的弧度
        /// \param antiClockwise 顺逆方向，true：逆时， false：顺时
        /// \return 二维圆弧
        /// \see 要求三点不重合且不共线
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc2d> Create(
            const Vector2d & centerPoint,
            const Vector2d & startPoint,
            const Vector2d & endPoint,
            bool antiClockwise
        );

        /// \brief 根据圆心、半径，参数范围，以及顺逆方向来构造圆弧
        /// \param centerPoint 圆心
        /// \param radius 半径
        /// \param range 参数范围，参数意义为Intervald(dStartAngle * dRadius * antiClockwise, dEndAngle * dRadius * antiClockwise)
        /// \param antiClockwise 顺逆方向，true：逆时， false：顺时
        /// \return 二维圆弧
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc2d> Create(
            const Vector2d & centerPoint,
            double radius,
            const Intervald & range,
            bool antiClockwise = true
        );


    public:

        /// \brief 获取圆心
        /// \return 圆心
        virtual Vector2d GetCenter() const = 0;

        /// \brief 设置圆心
        /// \param centerPoint 圆心
        /// \return 成功返回true，失败返回false
        virtual bool SetCenter(const Vector2d& centerPoint) = 0;

        /// \brief 获取半径
        /// \return 半径
        virtual double GetRadius() const = 0;

        /// \brief  设置半径
        /// \param radius 半径
        /// \return 成功返回true，失败返回false
        virtual bool SetRadius(double radius) = 0;

        /// \brief 获取起始角度(弧度)
        /// \return 起始角度(弧度)
        virtual double GetStartAngle() const = 0;

        /// \brief  获取终止角度(弧度)
        /// \return 终止角度(弧度)
        virtual double GetEndAngle() const = 0;

        /// \brief 通过三点重新定义当前圆弧
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param referencePoint    参考点
        /// \return 成功返回true，失败返回false
        virtual bool Set(const Vector2d & startPoint, const Vector2d& endPoint, const Vector2d& referencePoint) = 0;

        /// \brief  获取顺时针或逆时针方向，true：逆时， false：顺时
        /// \return 时针方向
        virtual bool IsAntiClockwise() const = 0;

        /// \brief  设置顺时针或逆时针方向
        /// \param antiClockwise  时针方向, true：逆时， false：顺时
        virtual void SetAntiClockwise(bool antiClockwise) = 0;

    public:
        virtual ~IArc2d() {}
    };
}
